﻿using System;
using System.Text;

using zijian666.Abstractions;
using zijian666.Convertor.Base;
using zijian666.Core;
using zijian666.ConvertExtensions;

namespace zijian666.Convertor;

/// <summary>
/// <seealso cref="byte" /> 数组转换器
/// </summary>
public class BytesConvertor : AllowNullConvertor<byte[]>, IFromConvertible<byte[]>, IFrom<Guid, byte[]>
{
    /// <inheritdoc/>
    public ConvertResult<byte[]> From(IConvertContext context, string input) => input.Length == 0 ? ArrayHelper<byte>.ENPTY : (context.Settings.Encoding ?? Encoding.UTF8).GetBytes(input);

    /// <inheritdoc/>
    public ConvertResult<byte[]> From(IConvertContext context, bool input) => BitConverter.GetBytes(input);

    /// <inheritdoc/>
    public ConvertResult<byte[]> From(IConvertContext context, char input) => BitConverter.GetBytes(input);

    /// <inheritdoc/>
    public ConvertResult<byte[]> From(IConvertContext context, sbyte input) => BitConverter.GetBytes((short)input);

    /// <inheritdoc/>
    public ConvertResult<byte[]> From(IConvertContext context, byte input) => BitConverter.GetBytes((short)input);

    /// <inheritdoc/>
    public ConvertResult<byte[]> From(IConvertContext context, short input) => BitConverter.GetBytes(input);

    /// <inheritdoc/>
    public ConvertResult<byte[]> From(IConvertContext context, ushort input) => BitConverter.GetBytes(input);

    /// <inheritdoc/>
    public ConvertResult<byte[]> From(IConvertContext context, int input) => BitConverter.GetBytes(input);

    /// <inheritdoc/>
    public ConvertResult<byte[]> From(IConvertContext context, uint input) => BitConverter.GetBytes(input);

    /// <inheritdoc/>
    public ConvertResult<byte[]> From(IConvertContext context, long input) => BitConverter.GetBytes(input);

    /// <inheritdoc/>
    public ConvertResult<byte[]> From(IConvertContext context, ulong input) => BitConverter.GetBytes(input);

    /// <inheritdoc/>
    public ConvertResult<byte[]> From(IConvertContext context, float input) => BitConverter.GetBytes(input);

    /// <inheritdoc/>
    public ConvertResult<byte[]> From(IConvertContext context, double input) => BitConverter.GetBytes(input);

    /// <inheritdoc/>
    public ConvertResult<byte[]> From(IConvertContext context, decimal input)
    {
        var arr = decimal.GetBits(input);
        var bytes = new byte[arr.Length << 2];
        Buffer.BlockCopy(arr, 0, bytes, 0, bytes.Length);
        return bytes;
    }

    /// <inheritdoc/>
    public ConvertResult<byte[]> From(IConvertContext context, DateTime input) => context.ConvertFail(this, input);

    /// <inheritdoc/>
    public ConvertResult<byte[]> From(IConvertContext context, Guid input) => input.ToByteArray();

}
